use crate::{Error, Result};
use axum::{http::Request, middleware::Next, response::Response};
use lazy_regex::regex_captures;
use tower_cookies::Cookies;

use super::AUTH_TOKEN;

pub async fn mv_require_auth<B>(cookies: Cookies, req: Request<B>, next: Next) -> Result<Response> {
    println!("--> {:<12} - mv_require_auth", "MW");

    let auth_token = cookies.get(AUTH_TOKEN).map(|c| c.value().to_string());

    let auth_token = cookies.get(AUTH_TOKEN).map(|c| c.value().to_string());

    //Parse Token
    let (user_id, expiration, signature) = auth_token
        .ok_or(Error::AuthFailNoAuthToken)
        .and_then(parse_token)?;

    // TODO: Token components validation

    auth_token.ok_or(Error::AuthFailNoAuthToken)?;
    Ok(next.run(req).await)
}

/// Parse a tokenof format 'user-[userid].[expiration].[signature]'
/// Returns (user_id, expiration, signature)
fn parse_token(token: String) -> Result<(u64, String, String)> {
    let (_whole, user_id, expiration, signature) =
        regex_captures!(r#"^user-(\d+)\.(.+)\.(.+)"#, &token)
            .ok_or(Error::AuthFailTokenWrongFormat)?;
    let user_id: u64 = user_id
        .parse()
        .map_err(|_| Error::AuthFailTokenWrongFormat)?;

    Ok((user_id, expiration.to_string(), signature.to_string()))
}
